#include <iostream>
#include <cstdio>
#include <sstream>
#include <map>
#include <semaphore.h>
#include "../serversocket.h"
#include "../socket.h"


std::map<Socket*,std::string> clientes;
sem_t espera;

void* recebeMensagem(void* socket) {
    Socket* cliente = (Socket*)socket;


    std::string inFromClient;
    while(1) {

        sem_wait(&espera);
        cliente->receiveMessage(inFromClient);
        std::cout << "Socket# " << (*cliente)() << " diz: " << inFromClient << "\n";
        sem_post(&espera);
    }
    close((*cliente)());
    return socket;
}

void* enviaMensagem(void* socket) {
    Socket* cliente = (Socket*)socket;

    while(1) {
        std::string outToClient;
        getline(std::cin, outToClient);
        cliente->sendMessage(outToClient);
    }
    close((*cliente)());
    return socket;
}


void* recebeCliente(void* socketNumber) {
    std::cout << "Conectei..\n";

    pthread_t sendThread, receiveThread;

    std::cout << "Criei duas threads\n";
    pthread_create(&sendThread, 0, enviaMensagem, socketNumber);
    pthread_create(&receiveThread, 0 , recebeMensagem, socketNumber);


    pthread_join(sendThread, NULL);
    pthread_join(receiveThread, NULL);


    return socketNumber;
}


int main(int argc, char *argv[])
{

    sem_init(&espera, 0, 1);
    ServerSocket ss;
    pthread_t thread, thread2;


    ss.listenConnection();
    Socket* client = new Socket();
    while(1) {
        (*client)() = ss.acceptConnection();
        if((*client)() >= 0) {
            std::string user;
            client->receiveMessage(user);
            clientes[client] = user;
            std::cout << user << ", socket #" << (*client)() << " conectou!\n";
            for(std::map<Socket*,std::string>::const_iterator i = clientes.begin(); i != clientes.end(); ++i) {
                std::cout << "Socket# " << (*(i->first))() << " -- Nome:" << i->second << "\n";
            }

            pthread_create(&thread, 0, recebeMensagem, (void*)client);
            pthread_create(&thread2, 0, enviaMensagem, (void*) client);
            //pthread_create(&thread,NULL, recebeCliente, (void*)client);
            //pthread_detach(thread);
        }
    }


}




